package main

import "fmt"

type Template interface {
	BoilWater()        // 烧水
	Brew()             // 冲泡
	AddSugar()         // 加糖
	HasAddSugar() bool // 是否加糖
}

type Coffee struct {
}

func (Coffee) BoilWater() { fmt.Println("烧水") }
func (Coffee) Brew()      { fmt.Println("冲泡") }
func (Coffee) AddSugar()  { fmt.Println("加糖") }
func (Coffee) HasAddSugar() bool {
	return true
}

type Tea struct {
}

func (Tea) BoilWater() { fmt.Println("烧水") }
func (Tea) Brew()      { fmt.Println("冲泡") }
func (Tea) AddSugar()  { fmt.Println("加糖") }
func (Tea) HasAddSugar() bool {
	return false
}

// main
//
//	@Description: 它定义了一个算法的骨架，并将某些步骤延迟到子类中实现。模板方法模式的核心思想是 将算法的通用部分放在父类中，而将可变部分交给子类实现。
//
// 通过模板方法模式，可以避免代码重复，并确保算法的结构不变。
func main() {
	tea := Tea{}
	coffee := Coffee{}
	MakeTemplate(tea)
	fmt.Println()
	MakeTemplate(coffee)
}

func MakeTemplate(tmp Template) {
	tmp.BoilWater()
	tmp.Brew()
	if tmp.HasAddSugar() {
		tmp.AddSugar()
	}
}
